home *** CD-ROM | disk | FTP | other *** search
/ Aminet 1 (Walnut Creek) / Aminet - June 1993 [Walnut Creek].iso / aminet / util / crypt / idea.lha / orig_crypt.c < prev    next >
C/C++ Source or Header  |  1992-05-12  |  5KB  |  134 lines

  1. /******************************************************************************/
  2. /*                                                                            */
  3. /*               C R Y P T O G R A P H I C - A L G O R I T H M S              */
  4. /*                                                                            */
  5. /******************************************************************************/
  6. /* Author:       Richard De Moliner (demoliner@isi.ethz.ch)                   */
  7. /*               Signal and Information Processing Laboratory                 */
  8. /*               Swiss Federal Institute of Technology                        */
  9. /*               CH-8092 Zuerich, Switzerland                                 */
  10. /* Last Edition: 23 April 1992                                                */
  11. /* System:       SUN SPARCstation, SUN cc C-Compiler, SUN-OS 4.1.1            */
  12. /******************************************************************************/
  13. #include <crypt.h>
  14.  
  15. #define mulMod        0x10001 /* 2**16 + 1                                    */
  16. #define addMod        0x10000 /* 2**16                                        */
  17. #define ones           0xFFFF /* 2**16 - 1                                    */
  18.  
  19. #define nofKeyPerRound      6 /* number of used keys per round                */
  20. #define nofRound            8 /* number of rounds                             */
  21.  
  22. /******************************************************************************/
  23. /*                          A L G O R I T H M                                 */
  24. /******************************************************************************/
  25. /* multiplication                                                             */
  26.  
  27. u_int32 Mul(a, b)
  28.  
  29. u_int32 a, b;
  30. { int32 p;
  31.   u_int32 q;
  32.   
  33.   if (a == 0) p = mulMod - b; 
  34.   else if (b == 0) p = mulMod - a;
  35.   else { q = a * b; p = (q & ones) - (q >> 16); if (p <= 0) p += mulMod; }
  36.   return (u_int32)(p & ones);
  37. } /* Mul */
  38.  
  39. /******************************************************************************/
  40. /* compute inverse of 'x' by Euclidean gcd algorithm                          */
  41.  
  42. u_int16 MulInv(x)
  43.  
  44. u_int16 x;
  45. { int32 n1, n2, q, r, b1, b2, t;
  46.  
  47.   if (x == 0) return 0;
  48.   n1 = mulMod; n2 = (int32)x; b2 = 1; b1 = 0;
  49.   do {
  50.     r = (n1 % n2); q = (n1 - r) / n2;
  51.     if (r == 0) { if (b2 < 0) b2 = mulMod + b2; }
  52.     else { n1 = n2; n2 = r; t = b2; b2 = b1 - q * b2; b1 = t; }
  53.   } while (r != 0);
  54.   return (u_int16)b2;
  55. } /* MulInv */
  56.  
  57. /******************************************************************************/
  58. /* encryption and decryption algorithm IDEA                                   */
  59.  
  60. void  Idea(dataIn, dataOut, key)
  61.  
  62. u_int16 *dataIn, *dataOut, *key;
  63. { register u_int32 round, x0, x1, x2, x3, t0, t1, t2;
  64.  
  65.   x0 = (u_int32)*(dataIn++); x1 = (u_int32)*(dataIn++);
  66.   x2 = (u_int32)*(dataIn++); x3 = (u_int32)*(dataIn);
  67.   for (round = nofRound; round > 0; round--) {
  68.     x0 = Mul(x0, (u_int32)*(key++));
  69.     x1 = (x1 + (u_int32)*(key++)) & ones;
  70.     x2 = (x2 + (u_int32)*(key++)) & ones;
  71.     x3 = Mul(x3, (u_int32)*(key++));
  72.     t0 = Mul((u_int32)*(key++), x0 ^ x2);      
  73.     t1 = Mul((u_int32)*(key++), (t0 + (x1 ^ x3)) & ones);
  74.     t0 = (t0 + t1) & ones;
  75.     x0 ^= t1; x3 ^= t0;
  76.     t0 ^= x1; x1 = x2 ^ t1; x2 = t0;
  77.   }
  78.   *(dataOut++) = (u_int16)(Mul(x0, (u_int32)*(key++)));
  79.   *(dataOut++) = (u_int16)((x2 + (u_int32)*(key++)) & ones);
  80.   *(dataOut++) = (u_int16)((x1 + (u_int32)*(key++)) & ones);
  81.   *(dataOut) = (u_int16)(Mul(x3, (u_int32)*key));
  82. } /* Idea */
  83.  
  84. /******************************************************************************/
  85. /* invert decryption / encrytion key for IDEA                                 */
  86.  
  87. void InvertIdeaKey(key, invKey)
  88.  
  89. u_int16 *key, *invKey;
  90. { register int  i;
  91.   KeyT(dk);
  92.  
  93.   dk[nofKeyPerRound * nofRound + 0] = MulInv(*(key++));
  94.   dk[nofKeyPerRound * nofRound + 1] = (addMod - *(key++)) & ones;
  95.   dk[nofKeyPerRound * nofRound + 2] = (addMod - *(key++)) & ones;
  96.   dk[nofKeyPerRound * nofRound + 3] = MulInv(*(key++));
  97.   for (i = nofKeyPerRound * (nofRound - 1); i >= 0; i -= nofKeyPerRound) {
  98.     dk[i + 4] = *(key++);
  99.     dk[i + 5] = *(key++);
  100.     dk[i + 0] = MulInv(*(key++));
  101.     if (i > 0) {
  102.       dk[i + 2] = (addMod - *(key++)) & ones;
  103.       dk[i + 1] = (addMod - *(key++)) & ones;
  104.     }
  105.     else {
  106.       dk[i + 1] = (addMod - *(key++)) & ones;
  107.       dk[i + 2] = (addMod - *(key++)) & ones;
  108.     }
  109.     dk[i + 3] = MulInv(*(key++));
  110.   }
  111.   for (i = 0; i < keyLen; i++) invKey[i] = dk[i]; 
  112. } /* InvertIdeaKey */
  113.  
  114.  
  115. /******************************************************************************/
  116. /* expand user key of 128 bits to full key of 832 bits                        */
  117.  
  118. void ExpandUserKey(userKey, key)
  119.  
  120. u_int16 *userKey, *key;
  121. { register int i;
  122.  
  123.   for (i = 0; i < userKeyLen; i++) key[i] = userKey[i];
  124.   /* shifts */
  125.   for (i = userKeyLen; i < keyLen; i++) {
  126.     if ((i + 2) % 8 == 0)                    /* for key[14],key[22],..  */
  127.       key[i] = ((key[i - 7] & 127) << 9) ^ (key[i - 14] >> 7); 
  128.     else if ((i + 1) % 8 == 0)               /* for key[15],key[23],..  */
  129.       key[i] = ((key[i - 15] & 127) << 9) ^ (key[i - 14] >> 7); 
  130.     else
  131.       key[i] = ((key[i - 7] & 127) << 9 ) ^ (key[i - 6] >> 7);
  132.    }
  133. } /* ExpandUserKey */
  134.